package com.cloudfun.campusshare.util;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import lombok.SneakyThrows;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * Created by Huqin on 2020/4/21
 */
public class XmlUtil {

    private static final ObjectMapper XML_MAPPER = new XmlMapper();

    static {
        //反序列化时，若实体类没有对应的属性，是否抛出JsonMappingException异常，false忽略掉
        XML_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        //序列化是否绕根元素，true，则以类名为根元素
        XML_MAPPER.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
        //忽略空属性
        XML_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        //XML标签名:使用下划线的属性名，
        XML_MAPPER.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        //设置转换模式
        XML_MAPPER.enable(MapperFeature.USE_STD_BEAN_NAMING);
    }

    private XmlUtil() {
    }

    /**
     * 对象转xml
     * 需要和以下注解一起使用
     * {@link com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper}
     * {@link com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement}
     * {@link com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty}
     * {@link com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlCData}
     * {@link com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText}
     *
     * @param object
     * @return
     */
    @SneakyThrows
    public static String writeValueAsString(Object object) {
        return XML_MAPPER.writeValueAsString(object);
    }

    /**
     * xml转对象
     * 需要和注解一起使用
     * {@link com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper}
     * {@link com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement}
     * {@link com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty}
     * {@link com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlCData}
     * {@link com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText}
     *
     * @param content
     * @param valueType
     * @param <T>
     * @return
     */
    @SneakyThrows
    public static <T> T readValue(String content, Class<T> valueType) {
        return XML_MAPPER.readValue(content, valueType);
    }

    /**
     * XML转化为map
     * @param content
     * @return
     */
    public static SortedMap<String, Object> readValue(String content){
        SortedMap<String,Object> map  = new TreeMap<>();
        Document document = cn.hutool.core.util.XmlUtil.parseXml(content);
        Element rootElement = cn.hutool.core.util.XmlUtil.getRootElement(document);
        List<Element> elements = cn.hutool.core.util.XmlUtil.getElements(rootElement, null);
        elements.forEach(x ->{
            map.put(x.getTagName(),x.getTextContent());
        });
        return map;
    }
}
